import { BaseIap, IapStep, IapBody, IapButton, Vector2 } from './gameClass';

export var config = {
    zIndex: {
        bg: 1,
        effect: 7,
        galText: 6,
        btn: 3,
        option: 4,
        hoverText: 5,
    },
};

//@ts-ignore
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var imgObserver = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
        // console.log('attributes changed', mutation);
        if (mutation.type == 'attributes') {
            if (mutation.attributeName == 'imgbox-id') {
                //@ts-ignore
                if (mutation.target.hasAttribute('imgbox-id')) {
                    //@ts-ignore
                    mutation.target.removeAttribute('imgbox-id');
                }
            }
        }
    });
});

//#region 绘图

function createBody() {
    var rect = document.createElement('div');
    rect.style.position = 'relative';
    rect.style.border = 'none';
    rect.style.padding = '0';
    rect.style.margin = '0';
    rect.style.userSelect = 'none';
    rect.style.overflow = 'hidden';
    rect.classList.add('iap-body');
    return rect;
}

function createPlayButton(): HTMLElement {
    var button = document.createElement('div');
    button.style.position = 'absolute';
    button.style.left = '0%';
    button.style.right = '0%';
    button.style.bottom = '20%';
    button.style.textAlign = 'center';
    button.style.background = 'linear-gradient(45deg,transparent, white, transparent)';
    button.textContent = '点击我进行游玩';
    button.style.zIndex = '' + config.zIndex.btn;
    return button;
}

export function createImg(): HTMLImageElement {
    var imgEl = document.createElement('img');
    // imgEl.style.zIndex = '5';
    imgObserver.observe(imgEl, {
        attributes: true,
    });
    return imgEl;
}

function createAudio() {
    var audio: HTMLAudioElement = document.createElement('audio');
    audio.style.display = 'none';
    return audio;
}

function createVideo(): HTMLVideoElement {
    var video: HTMLVideoElement = document.createElement('video');
    video.style.display = 'none';
    video.style.zIndex = '1';
    return video;
}

function createGalText(): HTMLElement {
    var button = document.createElement('div');
    button.style.position = 'absolute';
    button.style.left = '0%';
    button.style.right = '0%';
    button.style.bottom = '0%';
    button.style.textAlign = 'center';
    button.style.background = 'linear-gradient(45deg,transparent, white, transparent)';
    button.textContent = '点击我进行游玩';
    button.style.zIndex = '' + config.zIndex.btn;
    button.style.padding = '5px';
    // button.style.textShadow = "2px 0px 10px black";
    return button;
}

function createHoverText(): HTMLElement {
    var button = document.createElement('div');
    button.classList.add('iap-hove-text');
    button.style.position = 'absolute';
    button.style.textAlign = 'center';
    button.textContent = '';
    button.style.color = '#64ff86';
    button.style.zIndex = '' + config.zIndex.hoverText;
    button.style.display = 'none';
    button.style.textShadow = 'black 0px 0px 3px';
    return button;
}

export default class Game {
    static current?: Game = undefined;

    IAP!: IapBody;
    el!: HTMLIFrameElement;
    body!: HTMLDivElement;
    bgEl!: HTMLImageElement;
    bgEl2!: HTMLImageElement;
    bgmAudio!: HTMLAudioElement;
    seAudio!: HTMLAudioElement;

    interaction: boolean = false; //是否可交互

    buCtr: boolean = false;

    clickImageDuration: number = -1;

    playButton!: HTMLElement;

    videoEl!: HTMLVideoElement;
    galEL!: HTMLElement;

    // sceneId?: string = undefined;
    currentStepId!: string;

    hoverTextEl!: HTMLElement;

    /**id映射表 */
    idMap: { [x: string]: BaseIap } = {};

    // notDestroyRecord: string[] = [];

    //场景中的对象
    gameObjectIds: string[] = [];

    //选择项
    optionGroup!: HTMLElement;

    size: Vector2 = new Vector2(0,0); 


    constructor(Iap: BaseIap) {
        this.IAP = <IapBody>Iap;
        this.el = document.createElement("iframe");
        this.el.style.minWidth = '200px';
        this.el.style.minHeight = '200px';
        this.el.style.width = "100%";
        this.el.style.height = "100%";
        this.el.style.border = "none";
        this.el.classList.add("iap-iframe");
    }

    start() {
        //初始化
        var iframe = this.el;
        var IAP = this.IAP;
        var game = this;
        var i;
        var contentWindow = this.el.contentWindow!;
        var contentDocument = this.el.contentDocument!;
        var contentHtml = contentDocument.getElementsByTagName("html")[0]!;
        //先赋值idMap和game
        this.IAP.depthChildForEach(function (iap) {
            var id = iap.id;
            if (game.idMap[id]) {
                throw new Error(`存在多个相同id为${id}节点`);
            }
            game.idMap[id] = iap;
            iap.game = game;
        });

        //遍历场景，赋值notDestroy

        var steps = this.IAP.findByTag<IapStep>(IapStep.tag);
        //自动赋值下一个步骤
        if (!this.IAP.nextStepID && steps.length > 0) {
            this.IAP.nextStepID = steps[0].id;
        }
        for (i = 0; i < steps.length; i++) {
            var step = steps[i];
            if (step.nextStepID != 'no' && step.nextStepID == null) {
                if (i == steps.length - 1) {
                    step.nextStepID = steps[0].id;
                }
                else {
                    step.nextStepID = steps[i+1].id;
                }
            }
        }

        if(this.IAP.size) {
            this.size.x = this.IAP.size.x;
            this.size.y = this.IAP.size.y;
            if(this.IAP.fontSize) {
                contentHtml.style.fontSize = (this.IAP.fontSize / this.size.x * contentWindow.innerWidth).toFixed(2) + "px";
            }
        }
        else {
            this.size.x = contentWindow.innerWidth;
            this.size.y = contentWindow.innerHeight;
        }
        
        //创建对象
     
        this.body = createBody();
        this.bgEl = createImg();
        this.bgEl.style.width = '100%';
        this.bgEl.src = IAP.cover;
        this.bgEl.style.zIndex = '' + config.zIndex.bg;
        this.bgEl.style.position = 'absolute';

        this.bgEl2 = createImg();
        this.bgEl2.style.width = '100%';
        this.bgEl2.src = IAP.cover;

        this.hoverTextEl = createHoverText();

        this.playButton = createPlayButton();
        this.body.appendChild(this.bgEl);
        this.body.appendChild(this.bgEl2);
        this.body.appendChild(this.playButton);
        this.body.appendChild(this.hoverTextEl);

        this.el.contentDocument?.body.appendChild(this.body);
        this.body.addEventListener('click', this.onBodyClick.bind(this));

        //加载样式
        var style = document.createElement("style");
        style.appendChild(document.createTextNode(require("./mycss.css")));
        this.el.contentDocument?.head.appendChild(style);


        this.optionGroup = document.createElement('div');
        this.optionGroup.style.position = 'absolute';
        this.optionGroup.style.zIndex = "" + config.zIndex.option;
        this.optionGroup.style.left = '50%';
        this.optionGroup.style.top = '10%';
        this.optionGroup.style.transform = 'translateX(-50%)';
        this.optionGroup.style.minWidth = '50%';
        this.body.appendChild(this.optionGroup); 

        //窗口离开事件
        document.addEventListener("visibilitychange", function() {
            if(game) {
                if (document.visibilityState == "hidden") {
                    game?.bgmAudio?.pause();
                }else if(document.visibilityState == "visible") {
                    game?.bgmAudio?.play();
                }
            }
        })

        this.resize();
        contentWindow.addEventListener("resize", this.resize.bind(this))
    }
    
    resize() {
        var contentWindow = this.el.contentWindow!;
        var contentDocument = this.el.contentDocument!;
        var contentHtml = contentDocument.getElementsByTagName("html")[0]!;
        this.el.style.height = this.IAP.size.y / this.IAP.size.x * contentWindow.innerWidth + "px";
        if(this.IAP.fontSize) {
            contentHtml.style.fontSize = (this.IAP.fontSize / this.size.x * contentWindow.innerWidth).toFixed(2) + "px";
        }
    }

    onBodyClick(e: Event) {
        if (!this.interaction) {
            this.interaction = true;
            this.playButton.style.display = 'none';

            this.IAP.children.forEach((c) => c.create);

            var nextID = this.IAP.nextStepID;
            if (nextID) {
                this.nextSceneById(nextID);
            }
        } else {
            var currentStep = <IapStep>this.idMap[this.currentStepId];
            if (!currentStep) return;

            var nextStepId = currentStep.nextStepID;
            if (nextStepId != 'no' && nextStepId != null ) {
                this.nextSceneById(nextStepId);
            }
        }
        e.stopPropagation();
        return false;
    }

    showBG(url: string) {
        if (this.bgEl) {
            this.bgEl.src = url;
            this.bgEl.style.display = '';
        }
        if (this.bgEl2) {
            this.bgEl2.src = url;
            this.bgEl.style.display = '';
        }
    }
    hideBG() {
        if (this.bgEl) {
            this.bgEl.style.display = 'none';
        }
        if (this.bgEl2) {
            this.bgEl.style.display = 'none';
        }
    }

    playSe(url: string, loop = false) {
        if (this.seAudio == null) {
            this.seAudio = createAudio();
            this.body.appendChild(this.seAudio);
        }
        if (url == null) {
            this.stopSe();
        } else {
            this.seAudio.src = url;
            this.seAudio.loop = loop;
            this.seAudio.play();
        }
    }

    playBGM(url: string, loop = true) {
        if (this.bgmAudio == null) {
            this.bgmAudio = createAudio();
            this.body.appendChild(this.bgmAudio);
        }
        if (url) {
            //@ts-ignore
            if (this.bgmAudio.iapUrp != url) {
                //@ts-ignore
                this.bgmAudio.iapUrp = url;
                this.bgmAudio.src = url;
                this.bgmAudio.play();
                this.bgmAudio.loop = loop;
            }
        }
    }

    stopSe() {
        if (this.seAudio) {
            this.seAudio.pause();
            this.seAudio.currentTime = 0;
        }
    }

    playVideo(url: string) {
        if (!this.buCtr) return;

        if (!this.videoEl) {
            this.videoEl = createVideo();
            this.videoEl.style.width = '100%';
            this.body.appendChild(this.videoEl);
        }
        this.bgEl.style.display = 'none';
        this.videoEl.style.display = '';
        this.videoEl.src = url;
        this.videoEl.play();
        this.videoEl.addEventListener('pause', function () {
            // console.log("视频播放结束");
            //恢复
        });
    }

    stopAndHideVideo() {
        if (this.videoEl) {
            this.videoEl.pause();
            this.videoEl.style.display = 'none';
        }
    }

    showGalText(text: string) {
        if (!this.galEL) {
            this.galEL = createGalText();
            this.galEL.style.zIndex = '' + config.zIndex.galText;
            this.body.appendChild(this.galEL);
        }
        this.galEL.style.display = '';
        this.galEL.textContent = text;
    }
    hideGalText() {
        if (this.galEL) {
            this.galEL.style.display = 'none';
        }
    }

    timeoutId: any;
    safeDurationRecord : number[] = [];

    nextSceneById(id: string) {
        //进入下一个step前的操作
        var currentStep = <IapStep>this.idMap[this.currentStepId];
        var nextStep = <IapStep>this.idMap[id];
        if(currentStep) {
            //销毁和离开销毁
            currentStep.destroy();
            this.forcedDestroy(currentStep.leaveDestroy);    
        }
        if(nextStep == null) {
            return;
        }

        //进入销毁
        this.forcedDestroy(nextStep.enterDestroy);
        this.currentStepId = id;
        if (nextStep == null) return;

        if (nextStep.video) {
            this.playVideo(nextStep.video);
            this.hideBG();
        } else if (nextStep.bg) {
            this.stopAndHideVideo();
            this.showBG(nextStep.bg);
        }
        if (nextStep.se) {
            this.playSe(nextStep.se, nextStep.loop);
        }
        if (nextStep.galText) {
            this.showGalText(nextStep.galText);
        } else {
            this.hideGalText();
        }
        if (nextStep.bgm) {
            this.playBGM(nextStep.bgm);
        }
        if (nextStep.fontSize) {
            this.IAP.fontSize = nextStep.fontSize;
            // this.playBGM(nextStep.bgm);
        }
        this.playEffects(nextStep.effects);
        nextStep.create();
        this.hoverTextEl.style.display = "none";

        if(typeof nextStep.duration == "number" && nextStep.duration >= 0) {
            if(this.timeoutId) {
                clearTimeout(this.timeoutId);
            }
            //安全检测
            this.safeDurationRecord.push(Date.now());
            var flag = true;
            if(this.safeDurationRecord.length > 5) {
                var inst = this.safeDurationRecord[this.safeDurationRecord.length - 1] - this.safeDurationRecord[0];
                if (inst < 1000) {
                    flag = false;
                    this.printError("自动一下个step，发现短时间多次触发，这是违规行为");
                    this.stopGame();
                } else {
                    this.safeDurationRecord.shift();
                }
            }
            if(flag)
            {
                this.timeoutId = setTimeout(()=> {
                    this.body.click();
                }, nextStep.duration * 1000);
            }
        }
    }

    printError(error: string) {
        console.error(error);
    }

    stopGame() {
    }


    forcedDestroy(ids: string[] | undefined) {
        if (ids && ids.length > 0) {
            for (let id of ids) {
                this.idMap[id].forcedDestruction();
            }
        }
    }

    playEffects(names: string[] | undefined) {
        if (!names) return;
        for (let name of names) {
            this.playEffect(name);
        }
    }

    /**屏幕闪特性 */
    playEffect(name: string) {
        switch (name) {
            case 'glint':
                {
                    var div = document.createElement('div');
                    div.style.zIndex = '' + config.zIndex.effect;
                    this.body.appendChild(div);
                    div.classList.add('iap-effect-glint');
                    setTimeout(() => div.remove(), 2 * 1000);
                }
                break;
            case 'shake':
                {
                    this.bgEl.classList.add('iap-effect-shake');
                    setTimeout(() => this.bgEl.classList.remove('iap-effect-shake'), 300);
                }
                break;
        }
    }

    calcFontSize(size: number | undefined) : string {
        if(size !== 0 && !!size && !this.IAP.fontSize) {
            return "1rem";
        }
        return (size! / this.IAP.fontSize!).toFixed(3) + "rem" ;
    }
}
